package com.ng.generator;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableFill;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

import java.util.Arrays;

/**
 * MyBatis Plus 通用代码生成类
 *
 * @author Ng
 * @date 2024/03/11
 */
public class CodeGenerator {

    // TODO 修改服务名以及数据表名
    private static final String SERVICE_NAME = "db_ng";
    private static final String DATA_SOURCE_USER_NAME  = "root";
    private static final String DATA_SOURCE_PASSWORD  = "$Ng123";
    private static final String[] TABLE_NAMES = new String[]{
        "tb_user",
    };

    // TODO 默认生成 Entity，需要生成 DTO、VO 修改此变量
    private static final Boolean IS_PO = true;
    private static final Boolean IS_DTO = false;
    private static final Boolean IS_VO = false;

    // 生成文件路径名 (com.example.generator.xxx)
    private static final String MODULE_NAME = "output";

    /**
     * Main 程序启动入口
     * @param args main
     */
    public static void main(String[] args) {

        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 选择 freemarker 引擎，默认 Velocity
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());

        // 设置模板
        TemplateConfig tc = new TemplateConfig();
        mpg.setTemplate(tc);

        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setFileOverride(true);
        gc.setOutputDir(System.getProperty("user.dir") + "/ng-generator/src/main/java");
        gc.setAuthor("Ng");
        gc.setOpen(false);
        gc.setBaseResultMap(true);
        gc.setBaseColumnList(true);
        gc.setServiceName("%sService");
        if (IS_DTO) {
            gc.setSwagger2(true);
            gc.setEntityName("%sDTO");
        } else if (IS_VO) {
            gc.setSwagger2(true);
            gc.setEntityName("%sVO");
        } else {
            gc.setSwagger2(false);
        }
        mpg.setGlobalConfig(gc);

        // 数据库配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl("jdbc:mysql://localhost:3306/" + SERVICE_NAME
                + "?serverTimezone=UTC&useUnicode=true&useSSL=false&characterEncoding=utf8");
        dsc.setDriverName("com.mysql.cj.jdbc.Driver");
        dsc.setUsername(DATA_SOURCE_USER_NAME);
        dsc.setPassword(DATA_SOURCE_PASSWORD);
        mpg.setDataSource(dsc);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(MODULE_NAME);
        pc.setParent("com.example.generator");
        pc.setServiceImpl("service.impl");
        pc.setXml("mapper");
        if (IS_DTO) {
            pc.setEntity("model.dto");
        } else if (IS_VO) {
            pc.setEntity("model.vo");
        } else {
            pc.setEntity("model.po");
        }
        mpg.setPackageInfo(pc);

        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        // 表名生成策略，underline_to_camel 转驼峰命名
        strategy.setNaming(NamingStrategy.underline_to_camel);
        // 列名生成策略，underline_to_camel 转驼峰命名
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // 是否使用 Lombok 优化代码
        strategy.setEntityLombokModel(true);
        // Controller 类是否直接返回 JSON
        strategy.setRestControllerStyle(true);
        // 要生成的表名
        strategy.setInclude(TABLE_NAMES);
        strategy.setControllerMappingHyphenStyle(true);
        // 生成的类名去掉前缀
        // strategy.setTablePrefix(pc.getModuleName() + "_");
        strategy.setTablePrefix("tb_");
        // Boolean 类型字段是否移除is前缀处理
        strategy.setEntityBooleanColumnRemoveIsPrefix(true);
        strategy.setRestControllerStyle(true);
        // 自动填充字段配置
        strategy.setTableFillList(Arrays.asList(
                new TableFill("create_time", FieldFill.INSERT),
                new TableFill("change_time", FieldFill.INSERT_UPDATE),
                new TableFill("modify_time", FieldFill.UPDATE)
        ));
        mpg.setStrategy(strategy);

        mpg.execute();
    }
}
